
#ifndef _VIDEO_COLOR_HPP
#define _VIDEO_COLOR_HPP

#include "../common.hpp"

namespace yep
{
    /**
     * @brief Encapsulates SDL_Color
     *
     * It contains all need constructors and cast operators to peform convertions
     *  to and from SDL_Color.
     **/
    struct Color
    {
        /**
         * @brief Contructs a color based on components
         **/
        Color( Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha = 0xFF )
        {
            internalColor = {red, green, blue, alpha};
        }

        /**
         * @brief Contructs based on the given SDL_Color
         **/
        Color( const SDL_Color &color, bool ignoreAlpha=false)
        {
            internalColor = color;
            if(ignoreAlpha)
                internalColor.unused = 0xFF;
        }

        /**
         * @brief Constructs based on a pixel and a pixel format.
         **/
        Color( Uint32 pixel, SDL_PixelFormat *format)
        {
            YEP_ASSERT(format);
            SDL_GetRGBA(pixel, format, &internalColor.r, &internalColor.g, &internalColor.b, &internalColor.unused);
        }

        /**
         * @brief Empty constructor
         **/
        Color()
        {
            internalColor = {0, 0, 0, 0};
        }

        /** @defgroup gettersAndSetters */
        /** @{ */

        /**
         * @brief Gets the red component
         **/
        Uint8 red() const
        {
            return internalColor.r;
        }

        /**
         * @brief Gets the green component
         **/
        Uint8 green() const
        {
            return internalColor.g;
        }

        /**
         * @brief Gets the blue component
         **/
        Uint8 blue() const
        {
            return internalColor.b;
        }

        Uint8 alpha() const
        {
            return internalColor.unused;
        }

        /**
         * @brief Sets the red Component
         **/
        Color &red(Uint8 value)
        {
            internalColor.r = value;
            return *this;
        }

        /**
         * @brief Sets the red Component
         **/
        Color &green(Uint8 value)
        {
            internalColor.g = value;
            return *this;
        }

        /**
         * @brief Sets the red Component
         **/
        Color &blue(Uint8 value)
        {
            internalColor.b = value;
            return *this;
        }

        Color &alpha(Uint8 value)
        {
            internalColor.unused = value;
            return *this;
        }

        /** @} */

        /**
         * @brief Converts the color to the surface's format
         **/
        Uint32 operator()( SDL_Surface* surface ) const
        {
            YEP_ASSERT(surface);
            return SDL_MapRGBA( surface->format, internalColor.r, internalColor.g, internalColor.b, internalColor.unused );
        }

        operator SDL_Color &()
        {
            return internalColor;
        }

        operator const SDL_Color &() const
        {
            return internalColor;
        }

        operator Uint32() const
        {
            return internalColor.r << 24 | internalColor.g << 16 | internalColor.b << 8 | internalColor.unused;
        }

        /** @defgroup colors */
        /** @{ */
        static const Color BLACK;
        static const Color BLUE;
        static const Color GREEN;
        static const Color CYAN;
        static const Color RED;
        static const Color PURPLE;
        static const Color YELLOW;
        static const Color LIGHT_GRAY;
        static const Color DARK_GRAY;
        static const Color LIGHT_BLUE;
        static const Color LIGHT_GREEN;
        static const Color LIGHT_CYAN;
        static const Color LIGHT_RED;
        static const Color LIGHT_PURPLE;
        static const Color LIGHT_YELLOW;
        static const Color WHITE;
        /** @} */
    private:
        SDL_Color internalColor;
    };
}

#endif // _VIDEO_COLOR_HPP

